home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’95 / ProcessBar™ / Code / Sources / main.c < prev    next >
Encoding:
Text File  |  1995-06-23  |  8.7 KB  |  317 lines  |  [TEXT/MMCC]

  1. // File "main.c" - 
  2.  
  3. //#include <Gestalt.h>
  4. #include <TextServices.h>
  5.  
  6. #include "main.h"
  7. #include "aevents.h"
  8. #include "filter.h"
  9. #include "floaters.h"
  10. #include "patches.h"
  11. #include "sample win.h"
  12.  
  13. #include "mdg.h"
  14.  
  15. // * ****************************************************************************** *
  16. // Global Declarations
  17.  
  18. GlobalsRec glob;
  19.  
  20. // * ****************************************************************************** *
  21. // * ****************************************************************************** *
  22.  
  23. void DoTest() {
  24.     short i;
  25.     long response;
  26.     
  27.     for(i=0; i<sizeof(glob); ((char *) &glob)[i++] = 0);
  28.     
  29.     // Simple Tests for compatibility
  30.     if (Gestalt(gestaltSystemVersion, &response) || (response < 0x0604) ||
  31.             Gestalt(gestaltTSMgrVersion, &response)) 
  32.         EmergencyExit("\p\"appe Windows\" requires System 7.1 or later");
  33.     
  34.     glob.bkgdOnly = ((** (short **) GetResource('SIZE', -1)) & 0x0400) ? TRUE : FALSE;
  35.     glob.hasColorQD = (! Gestalt(gestaltQuickdrawFeatures, &response) &&
  36.             (response & (1 << gestaltHasColor))) ? TRUE : FALSE;
  37.     glob.hasGDevices = (NGetTrapAddress(_GetDeviceList, ToolTrap) !=
  38.             NGetTrapAddress(_Unimplemented, ToolTrap)) ? TRUE : FALSE;
  39.     glob.hasDragMgr = (! Gestalt(gestaltDragMgrAttr, &response) &&
  40.             (response & (1 << gestaltDragMgrPresent))) ? TRUE : FALSE;
  41.     }
  42.  
  43. // * ****************************************************************************** *
  44. // * ****************************************************************************** *
  45.  
  46. void DoInit() {
  47.     long saveA5;
  48.     
  49.     // 'appe' programs get 8k of Stack Space by default -- we need MORE! 
  50.     if (glob.bkgdOnly) SetApplLimit(GetApplLimit() - 16384);
  51.     MaxApplZone();
  52.     MoreMasters();
  53.  
  54.     // Basic Initialization 
  55.     InitGraf(&qd.thePort);
  56.     
  57.     // Finish our Initialization - but only if we are a foreground app. Apple
  58.     //   warns loudly that bkgd-only apps should not call InitWindows(), etc.
  59.     if (! glob.bkgdOnly) {
  60.         InitFonts();
  61.         InitWindows();
  62.         InitMenus();
  63.         TEInit();
  64.         InitDialogs(0);
  65.         InitCursor();
  66.         
  67.         InsertMenu(GetMenu(kAppleMenuID), 0);
  68.         AppendResMenu(GetMenuHandle(kAppleMenuID), 'DRVR');
  69.         InsertMenu(GetMenu(kFileMenuID), 0);
  70.         InsertMenu(GetMenu(kEditMenuID), 0);
  71.         DisableItem(GetMenuHandle(kEditMenuID), 0);
  72.         
  73.         DrawMenuBar();
  74.         }
  75.       else {
  76.         // After reading the above, you know that you can't call any other toolbox
  77.         //   init stuff. However, FindServiceWindow() fails if the MenuList lomem 
  78.         //   global is NIL! This is a moderate (but not recommended) workaround.
  79.         InitFonts();
  80.         InitMenus();
  81.         }
  82.     
  83.     // Save this information for later
  84.     GetCurrentProcess(&glob.myPSN);    
  85.         
  86.     // Install an event filter or die
  87.     SetA5(saveA5 = SetA5(0));
  88.     glob.filterProc =
  89.             (Ptr) InstallEventFilter((FilterHelperUPP) EventFilterHelper, (Ptr) saveA5);
  90.     if (! glob.filterProc)
  91.         EmergencyExit("\p\"appe Windows\": An Unexpected Error Occurred");
  92.     
  93.     // if (kPatchOutNewWindow)
  94.     PatchNewWindow();
  95.     PatchExitToShell();
  96.     InitHLEvents();
  97.     }
  98.  
  99. // * ****************************************************************************** *
  100. // * ****************************************************************************** *
  101.  
  102. void DoLoop() {
  103.     Boolean floaterEvent;
  104.     
  105.     while(! glob.quitting) {
  106.         // If there are no internal events pending, then we call WNE() with a
  107.         //   moderate delay. Otherwise, we want to make a fast response to any 
  108.         //   floater events, so we make sure the event filter will wake us up quickly.
  109.         if (glob.forwardedEvents.qHead) glob.theEvent.what = nullEvent;
  110.           else WaitNextEvent(everyEvent, &glob.theEvent, 60, 0);    // Sleep for 1 secs
  111.         
  112.         // Check the states of our floaters, then generate and handle any 
  113.         //   pending Update Events for floaters because the Event Mgr will
  114.         //   not generate them for us.
  115.         ShowHideFloater(0);
  116.         UpdateFloater(0);
  117.  
  118.         // If nothing to do, then check our private event queue to see if any
  119.         //   clicks or keydowns are pending for our floater windows.
  120.         floaterEvent = (glob.theEvent.what != nullEvent) ? FALSE : 
  121.                 GetFloaterEvent(&glob.theEvent);
  122.         if(floaterEvent)
  123.         {
  124.         }
  125.         switch(glob.theEvent.what) {
  126.             case nullEvent:
  127.                 IdleTaskbar();
  128.                 break;
  129.             case mouseDown: {
  130.                 short thePart;
  131.                 Rect bounds;
  132.                 WindowPtr whichWin, frontWin;
  133.                 
  134.                 if (floaterEvent) {
  135.                     thePart = FindServiceWindow(glob.theEvent.where, &whichWin);
  136.                     if (GetFrontServiceWindow(&frontWin)) frontWin = 0;
  137.                     }
  138.                   else {
  139.                     thePart = FindWindow(glob.theEvent.where, &whichWin);
  140.                     frontWin = FrontWindow();
  141.                     }
  142.  
  143.                 glob.theEvent.message = thePart;        
  144.                 switch(thePart) {
  145.                     case inMenuBar:
  146.                         DoMenuItem(MenuSelect(glob.theEvent.where));
  147.                         break;
  148.                         
  149.                     case inSysWindow:
  150.                         SystemClick(&glob.theEvent, whichWin);
  151.                         break;
  152.                         
  153.                     case inDrag:
  154.                         if (whichWin != frontWin) {
  155.                             SelectWindow(whichWin);
  156.                             UpdateFloater(whichWin);
  157.                             }
  158.                         bounds = (*GetGrayRgn())->rgnBBox;
  159.                         DragWindow(whichWin, glob.theEvent.where, &bounds);
  160.                         UpdateFloater(whichWin);
  161.                         break;
  162.                         
  163.                     case inContent:
  164.                     case inGrow:
  165.                     case inGoAway:
  166.                     case inZoomIn:
  167.                     case inZoomOut:
  168.                         if (whichWin != frontWin) {
  169.                             SelectWindow(whichWin);
  170.                             UpdateFloater(whichWin);
  171.                             }
  172.                         EventDispatchFloaters(&glob.theEvent, whichWin);
  173.                         break;
  174.                     }
  175.                 break;
  176.                 }
  177.             case keyDown:
  178.             case autoKey: {
  179.                 char theKey, theChar;
  180.                 
  181.                 theChar = glob.theEvent.message & charCodeMask;
  182.                 theKey = (glob.theEvent.message & keyCodeMask) >> 8;
  183.                 
  184.                 if (glob.theEvent.modifiers & cmdKey)
  185.                     DoMenuItem(MenuKey(glob.theEvent.message & charCodeMask));
  186.                   else EventDispatchFloaters(&glob.theEvent, 0);
  187.                 }
  188.                 break;
  189.                     
  190.             case updateEvt:
  191.                 if (GetOneFloater((WindowPtr) glob.theEvent.message, FALSE))
  192.                     EventDispatchFloaters(&glob.theEvent, (WindowPtr) glob.theEvent.message);
  193.                 break;
  194.             case activateEvt:
  195.                 break;
  196.             case kHighLevelEvent:
  197.                 AEProcessAppleEvent(&glob.theEvent);
  198.                 break;
  199.             }
  200.         
  201.         // WARNING: Dont set the cursor to arrow just because it is over a floater
  202.         //   window -- most foreground apps are not smart enough to recognize a
  203.         //   the TSM floaters, and the cursor may start to flicker.
  204.         if (! glob.bkgdOnly) SetCursor(&qd.arrow);
  205.         }
  206.     }
  207.  
  208. // * ****************************************************************************** *
  209. // * ****************************************************************************** *
  210.  
  211. void DoMenuItem(long theMenuAndItem) {
  212.     short theMenu, theItem;
  213.     Str63 theString;
  214.     
  215.     if (! theMenuAndItem) return;
  216.     
  217.     theMenu = (theMenuAndItem & 0xFFFF0000) >> 16;
  218.     theItem = theMenuAndItem & 0x0000FFFF;
  219.     
  220.     switch(theMenu) {
  221.         case kAppleMenuID:
  222.             if (theItem == kAppleMenuAboutItem) {
  223.                 // Block out the floaters while we display our about box... 
  224.                 //   then enable and update them after we have finished.
  225.                 glob.modalFloats = TRUE;
  226.                 ShowHideFloater(0);
  227.                 
  228.                 Alert(128, 0);
  229.                 
  230.                 glob.modalFloats = FALSE;
  231.                 ShowHideFloater(0);
  232.                 UpdateFloater(0);
  233.                 }
  234.               else {
  235.                 GetMenuItemText(GetMenuHandle(theMenu), theItem, theString);
  236.                 OpenDeskAcc(theString);
  237.                 }
  238.             break;
  239.             
  240.         case kFileMenuID:
  241.             switch(theItem) {
  242. /*                case kFileMenuNewItem:
  243.                     NewSampleWindow();
  244.                     break;
  245. */
  246.                 case kFileMenuQuitItem:
  247.                     glob.quitting = TRUE;
  248.                     break;
  249.                 }
  250.             break;
  251.             
  252.         case kEditMenuID:
  253.             break;
  254.  
  255.         default:
  256.             break;
  257.         }
  258.     HiliteMenu(0);
  259.     DrawMenuBar();
  260.     }
  261.  
  262. // * ****************************************************************************** *
  263. // * ****************************************************************************** *
  264.  
  265. void DoDispose() {
  266.     static Boolean done = FALSE;
  267.     
  268.     // Our ExitToShell() patch may cause re-entrancy problems... so we bracket
  269.     //   the functional calls by checking and setting a one-time flag.
  270.     if (! done) {
  271.         done = TRUE;
  272.         
  273.         CloseRemainingFloaters();
  274.         
  275.         ReleaseEventFilter(glob.filterProc);
  276.         glob.filterProc = 0;
  277.         }
  278.     }
  279.  
  280. // * ****************************************************************************** *
  281. // * ****************************************************************************** *
  282.  
  283. void EmergencyExit(StringPtr whyString) {
  284.     NMRecPtr notify;
  285.     StringPtr sysString;
  286.  
  287.     sysString = (StringPtr) NewPtrSys(whyString[0]+1);
  288.     BlockMove(whyString, sysString, whyString[0]+1);
  289.  
  290.     // Since we may be an 'appe', we need a safe way to notify the user that we
  291.     //   cannot run. Post a Notification Mgr dialog and then ExitToShell().
  292.     
  293.     notify = (NMRecPtr) NewPtrSys(sizeof(*notify));
  294.     notify->qLink = 0;
  295.     notify->qType = nmType;
  296.     notify->nmMark = 0;
  297.     notify->nmIcon = 0;
  298.     notify->nmSound = (Handle) -1;
  299.     notify->nmStr = sysString;
  300.     notify->nmResp = 0; 
  301.     notify->nmRefCon = 0;    
  302.     NMInstall(notify);
  303.     
  304.     ExitToShell();
  305.     }
  306.     
  307. // * ****************************************************************************** *
  308. // * ****************************************************************************** *
  309.  
  310. void main() {
  311.     DoTest();
  312.     DoInit();
  313.     DoLoop();
  314.     DoDispose();
  315.     }
  316.     
  317.